package com.nulldev.util.security.encryptAPI_rw.api;

import static com.nulldev.util.manage.Macros.__assert;

import com.nulldev.util.data.Variables;
import com.nulldev.util.data.Charsets.CharsetUtil;

public interface IStandardBlockingCipherWithIV extends IStandardBlockingCipher {

	@Override
	default ICipherType getCipherType() {
		return ICipherType.PRIVATE_KEY_IV;
	}

	public byte[] encrypt(final byte[] data, final byte[] key, final byte[] iv);

	public default byte[] encrypt(final String data, final byte[] key, final byte[] iv) {
		return encrypt(Variables.requireNonNullObject(data, "data").getBytes(CharsetUtil.UTF_8), key, iv);
	}

	public default byte[] encrypt(final byte[] data, final String key, final byte[] iv) {
		return encrypt(data, Variables.requireNonNullObject(key, "key").getBytes(CharsetUtil.UTF_8), iv);
	}

	public default byte[] encrypt(final String data, final String key, final byte[] iv) {
		return encrypt(Variables.requireNonNullObject(data, "data").getBytes(CharsetUtil.UTF_8),
				Variables.requireNonNullObject(key, "key").getBytes(CharsetUtil.UTF_8), iv);
	}

	public byte[] decrypt(final byte[] data, final byte[] key, final byte[] nonce);

	public default byte[] decrypt(final String data, final byte[] key, final byte[] nonce) {
		return decrypt(Variables.requireNonNullObject(data, "data").getBytes(CharsetUtil.UTF_8), key, nonce);
	}

	public default byte[] decrypt(final byte[] data, final String key, final byte[] nonce) {
		return decrypt(data, Variables.requireNonNullObject(key, "key").getBytes(CharsetUtil.UTF_8), nonce);
	}

	public default byte[] decrypt(final String data, final String key, final byte[] nonce) {
		return decrypt(Variables.requireNonNullObject(data, "data").getBytes(CharsetUtil.UTF_8),
				Variables.requireNonNullObject(key, "key").getBytes(CharsetUtil.UTF_8), nonce);
	}

	public static void __validate_iv(final byte[] iv) {
		__assert(iv == null, "IV cannot be null!");
		__assert(iv.length != 16, "IV must be 16 bytes! (128 bits)");
	}
}
